import { expect } from '@jest/globals';
import * as fse from 'fs-extra';
import path from 'path';

import { getJson5Obj } from '../../../../src/utils/json-util';
import {
  addDependency,
  addRuntimeOnly,
  hasCommonElements,
  initExecuteCommand,
  runHvigorAsync
} from '../../common/common';
import {
  AbilityType,
  APIType,
  APIVersion, CaseLevel,
  LanguageType, ModuleTemplateType,
  RuntimeOSType,
  SDKType
} from '../../plugins/project-builder/models/constants';
import { TestCaseBuilder } from '../../plugins/task-builder/task-case-builder';
import { ProjectBuildOption, TestCaseFun } from '../../plugins/task-builder/test-case';
import { TestTaskOptionBuilder } from '../../plugins/task-builder/test-task-option';

const projectBuilderOption: ProjectBuildOption = {
  template: {
    sdk: SDKType.Single,
    runtimeOS: RuntimeOSType.HarmonyOS,
    apiVersion: APIVersion.API11,
    apiType: APIType.STAGE,
    language: LanguageType.ArkTs,
    abilityType: AbilityType.Application,
    entryTemplateType: ModuleTemplateType.EmptyAbility
  },
  modulesOption: {
    [ModuleTemplateType.StaticLibrary]: 3
  }
};

const testFun: TestCaseFun = async (project, taskConfig, record) => {
  const commandsHar = initExecuteCommand({
    sync: true,
    mode: 'module',
    module: 'staticLibrary@default',
    product: 'default',
    buildMode: 'release',
    tasks: 'assembleHar'
  });

  // 新增文件
  const libraryModuleRootPath = project.getModule('staticLibrary').moduleRootPath();
  await fse.mkdir(path.resolve(libraryModuleRootPath, 'src/main/staticLibrary_test'));
  await fse.writeFile(
    path.join(libraryModuleRootPath, 'src/main', 'staticLibrary_test/test.ets'), '');
  await fse.writeFile(
    path.join(libraryModuleRootPath, 'src/main', 'test1.ts'), '');
  await fse.writeFile(
    path.join(libraryModuleRootPath, 'src/main', 'test2.js'), '');

  const library1ModuleRootPath = path.resolve(project.getModule('staticLibrary1').moduleRootPath());
  await fse.mkdir(path.resolve(library1ModuleRootPath, 'src/main/staticLibrary1_test'));
  await fse.writeFile(
    path.join(library1ModuleRootPath, 'src/main', 'staticLibrary1_test/test3.ets'), '');
  await fse.writeFile(
    path.join(library1ModuleRootPath, 'src/main', 'test4.ts'), '');
  await fse.writeFile(
    path.join(library1ModuleRootPath, 'src/main', 'test5.js'), '');

  // 添加依赖
  await addDependency(libraryModuleRootPath, { 'staticLibrary1': 'file:../staticLibrary1' });
  await addDependency(library1ModuleRootPath, { 'staticLibrary2': 'file:../staticLibrary2' });

  // 添加动态import配置
  await addRuntimeOnly(libraryModuleRootPath,
    ['./src/main/staticLibrary_test/test.ets', './src/main/test1.ts', './src/main/staticLibrary_test'],
    ['staticLibrary1']);
  await addRuntimeOnly(library1ModuleRootPath,
    ['./src/main/staticLibrary1_test/test3.ets', './src/main/test4.ts', './src/main/staticLibrary1_test'],
    ['staticLibrary2']);

  const result = await runHvigorAsync(project.projectRootPath(), commandsHar);

  // 检查assembleHar正常完成
  expect(result.stdout).toContain('Finished :staticLibrary:assembleHar');

  // 检查loader.json的compileEntry
  const loaderJsonObj =
    getJson5Obj(path.resolve(libraryModuleRootPath, 'build/default/intermediates/loader/default/loader.json'));
  const compileEntry = [
    path.resolve(libraryModuleRootPath, 'src/main/ets/components/mainpage//MainPage.ets'),
    path.resolve(libraryModuleRootPath, 'src/main/staticLibrary_test/test.ets'),
    path.resolve(libraryModuleRootPath, 'src/main/test1.ts'),
    path.resolve(library1ModuleRootPath, 'src/main/staticLibrary1_test/test3.ets'),
    path.resolve(library1ModuleRootPath, 'src/main/test4.ets'),
    path.resolve(library1ModuleRootPath, 'index.ets'),
    path.resolve(project.getModule('staticLibrary1').moduleRootPath(), 'index.ets')
  ];
  expect(hasCommonElements(loaderJsonObj.compileEntry, compileEntry)).toBe(true);

  // 检查loader.json的dynamicImportLibInfo
  expect(Object.prototype.hasOwnProperty.call(loaderJsonObj.dynamicImportLibInfo, 'staticLibrary1')).toBe(true);
  expect(Object.prototype.hasOwnProperty.call(loaderJsonObj.dynamicImportLibInfo, 'staticLibrary2')).toBe(true);
};

TestCaseBuilder.builder()
  .caseName('OPENLAB_AIDE_ZOS_DEVECO_STUDIO_BUILD_STAGE_DYNAMIC_IMPORT_SET_027')
  .description('1、新建工程，添加har模块，配置成闭源har，har/src/main下创建har_test/test.ets、test1.ts、test2.js\n' +
    '2、添加har1模块，har2模块\n' +
    '3、har1/src/main下创建har1_test/test3.ets、test4.ts、test5.js\n' +
    '4、在har1/oh-package.json中的dependencies中配置har2依赖，' +
    'har1/build-profile.json5.buildOptionSet.release.arkOptions.runtimeOnly配置sources：test3.ets、test4.ts文件相对路径' +
    '和har1_test目录相对路径，packages：har2\n' +
    '5、在har/oh-package.json中的dependencies中配置har1依赖\n' +
    '6、在har/build-profile.json5.buildOptionSet.release.arkOptions.runtimeOnly配置' +
    'sources：test.ets、test1.ts文件相对路径和har_test目录相对路径，packages：har1\n' +
    '7、product按钮中buildMode选择release，构建har，检查har包\n' +
    '8、检查har/build/{product}/intermediates/loader/{target}/loader.json')
  .projectBuilderOption(projectBuilderOption)
  .taskConfig(TestTaskOptionBuilder.builder().caseLevel(CaseLevel.L1).build())
  .testFun(testFun)
  .load();
